﻿Imports System.Net.Sockets
Imports System.Net

Namespace UDPBroadcast

    Public Class Client
        Implements IDisposable

        Private Client As UdpClient
        Private m_port As Integer = 65432
        Private m_BroadCastAddress As IPAddress = IPAddress.Parse("224.224.224.224")

        Public ReadOnly Property Port() As Integer
            Get
                Return Me.m_port
            End Get
        End Property

        Public ReadOnly Property BroadcastAddress() As IPAddress
            Get
                Return Me.m_BroadCastAddress
            End Get
        End Property

        Public Sub New()
            Me.Client = New UdpClient()
        End Sub

        Public Sub New(ByVal s As UDPBroadcast.Server)
            Me.Client = New UdpClient()
            Me.m_BroadCastAddress = s.BroadcastAddress
            Me.m_port = s.Port
        End Sub

        Public Sub Query()
            Me.SendMessage(New QueryMessagePackage())
        End Sub

        Public Sub SendIdentity()
            Me.SendMessage(New IdentityMessagePackage())
        End Sub

        Public Sub Online()
            Me.SendMessage(New OnlineMessagePackage())
        End Sub

        Public Sub Offline()
            Me.SendMessage(New OfflineMessagePackage())
        End Sub

        Public Sub SendMessage(Of T)(ByVal message As T)
            If TypeOf message Is MessagePackageBase Then
                Dim data As Byte() = GenericCast(Of T, MessagePackageBase)(message).GetPackageData()
                Me.Client.Send(data, data.Length, New IPEndPoint(Me.BroadcastAddress, Me.Port))
            Else
                Me.SendMessage(New DataMessagePackage(Of T)(DateTime.Now, message))
            End If
        End Sub

        Public Sub SendMessage(message As MessagePackageBase)
            Dim data As Byte() = message.GetPackageData()
            Me.Client.Send(data, data.Length, New IPEndPoint(Me.BroadcastAddress, Me.Port))
        End Sub

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: dispose managed state (managed objects).
                    Me.Client.Close()
                End If
                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
                Me.Client = Nothing
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        Protected Overrides Sub Finalize()
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(False)
            MyBase.Finalize()
        End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

End Namespace